package cn.jiedanba.cacert.tsaserver.service.impl;

import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.List;

import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.jiedanba.cacert.common.ca.PkiUtil;
import cn.jiedanba.cacert.common.ca.cert.enums.CertStatusEnum;
import cn.jiedanba.cacert.common.ca.crl.tsa.PkiTsaUtil;
import cn.jiedanba.cacert.common.ca.crl.tsa.domain.TsaSign;
import cn.jiedanba.cacert.common.config.Configs;
import cn.jiedanba.cacert.common.result.ResponseResult;
import cn.jiedanba.cacert.mapper.SysCertMapper;
import cn.jiedanba.cacert.model.SysCert;
import cn.jiedanba.cacert.tsaserver.service.TsaService;
import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class TsaServiceImpl implements TsaService {

	@Autowired
	private SysCertMapper sysCertMapper;

	/**
	 * 时间戳
	 * 
	 * @param req
	 * @return
	 */
	@Override
	public ResponseResult sign(byte[] req) {
		try {

			String certId = Configs.get("tsa.cert");
			SysCert sysCert = sysCertMapper.selectOneById(certId);
			if (sysCert == null) {
				return ResponseResult.fail("未配置时间戳证书");
			}

			if (sysCert.getStatus().equals(CertStatusEnum.REVOKE.code)) {
				return ResponseResult.fail("时间戳证书已被吊销");
			}

			String[] algorithm = sysCert.getSigAlgName().split("With");
			String hashAlgorithm = algorithm[0];
			String signatureAlgorithm = algorithm[1];
			X509Certificate tspSigningCert = PkiUtil.readX509Certificate(Base64.decodeBase64(sysCert.getSignCert()));
			Boolean isTsaCert = false;
			List<String> usages = tspSigningCert.getExtendedKeyUsage();
			if (usages != null && !usages.isEmpty()) {
				for (String usage : usages) {
					// 是时间戳证书
					if (usage.equals("1.3.6.1.5.5.7.3.8")) {
						isTsaCert = true;
						break;
					}
				}
			} else {
				return ResponseResult.fail("时间戳证书错误");
			}
			if (!isTsaCert) {
				return ResponseResult.fail("时间戳证书错误");
			}

			PrivateKey tspSigningKey = PkiUtil.getPrivateKey(Base64.decodeBase64(sysCert.getPrivateKey()));

			TsaSign tsaSign = new TsaSign();
			tsaSign.setTspSigningCert(tspSigningCert);
			tsaSign.setTspSigningKey(tspSigningKey);
			tsaSign.setSignatureAlgorithm(signatureAlgorithm);
			tsaSign.setHashAlgorithm(hashAlgorithm);
			tsaSign.setEncRequest(req);
			byte[] signd = PkiTsaUtil.createTspResponse(tsaSign);
			return ResponseResult.success(signd);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return ResponseResult.error("时间戳签名异常");
		}

	}

}
